using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Grid : MonoBehaviour
{
	public int row;
	public int column;
	public int mine;
	public int itemSize;
	int[,] jump = new int[8, 2] {
		{-1, -1}, {-1, 0}, {-1, 1},
		{0, -1}, {0, 1},
		{1, -1}, {1, 0}, {1, 1}
	};

	public int[,] ids;
	public Item[,] items;
	public List<Item> mines;
	RectTransform rect;


	// Start is called before the first frame update
	void Start() {
		rect = transform.parent.parent.GetComponent<RectTransform>();
		Debug.Log(rect.sizeDelta);
		mines = new List<Item>();
		// GenerateInitGrid(row, column, mine);
		// 9 * 9 -> 10
		// 16*16 -> 40
		// 16*30 -> 99
		// GameObject
	}

	// Update is called once per frame
	void Update() {
		
	}


	/// <summary>
	/// 生成初始化表格
	/// </summary>
	/// <param name="row">行</param>
	/// <param name="column">列</param>
	/// <param name="mine">雷数量</param>
	public void GenerateInitGrid(int row, int column, int mine, int size) {
		itemSize = size;
		GetComponent<GridLayoutGroup>().cellSize = new Vector2(itemSize, itemSize);

		rect.sizeDelta = new Vector2(column * itemSize, row * itemSize);
		this.row = row;
		this.column = column;
		ids = new int[row, column];
		items = new Item[row, column];
		mine = mine > ids.Length ? ids.Length : mine;

		int[] mines = new int[ids.Length];  // 雷的位置
		for (int i = 0; i < mines.Length; i++) mines[i] = i;
		for (int i = 0; i < 100; i++) {      // 打乱顺序
			int a = Random.Range(0, mines.Length);
			int b = Random.Range(0, mines.Length);
			// Debug.Log(a + " " + b);
			int t = mines[a];
			mines[a] = mines[b];
			mines[b] = t;
		}

		int K = mines.Length / mine;
		int cnt = 0;
		for (int i = 0; i < mines.Length; i += K) {    // 得出雷位置
			if (cnt < mine) {         // 是雷
				cnt++;
				int x = mines[i] / column;
				int y = mines[i] % column;
				// Debug.Log(x + " " + y);
				ids[x, y] = -1;     // 表示该位置是雷
			}
		}

		// Debug.Log(cnt + ":" + mine);

		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				if (ids[i, j] != -1) {
					int cnt1 = 0;
					for (int k = 0; k < 8; k++) {
						int xt = i + jump[k, 0];
						int yt = j + jump[k, 1];
						if (IsGrid(xt, yt) && ids[xt, yt] == -1)
							cnt1++;
					}
					ids[i, j] = cnt1;
				}
			}
		}
		StartCoroutine(ShowGrid());
	}

	/// <summary>
	/// 协程加载, 实现动画效果
	/// </summary>
	/// <returns></returns>
	IEnumerator ShowGrid() {
		yield return null;
		List<Item>[] its = new List<Item>[7];
		for (int i = 0; i < its.Length; i++)
			its[i] = new List<Item>();

		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				items[i, j] = Item.GenerateInitItem(ids[i, j], transform);
				items[i, j].transform.localScale = Vector3.zero;
				items[i, j].id = i * column + j;

				int k = (i * column + j) % its.Length;
				int r = Random.Range(0, its.Length);
				k = (k + r) % its.Length;
				its[k].Add(items[i, j]);
				if (ids[i, j] == -1) mines.Add(items[i, j]);        // 所有炸弹添加到链表
			}
		}

		for (int i = 0; i < its.Length; i++) {
			int loop = 3;
			while (loop-- > 0)
				yield return null;
			foreach (var item in its[i]) {
				item.transform.localScale = Vector3.one;
			}
		}
	}



	/// <summary>
	/// 左键点击了数字
	/// </summary>
	/// <param name="id"></param>
	public void OnClickNum0(int id) {
		int x = id / column;
		int y = id % column;
		dfs(x, y, items[x, y].num);
	}

	/// <summary>
	/// 左键点击了炸弹
	/// </summary>
	/// <param name="id"></param>
	public void OnClickMine0(int id) {
		Debug.Log("炸弹, 游戏结束");
		int x = id / column;
		int y = id % column;
		items[x, y].Show_UI("mine_bomb");
		items[x, y].flag = true;
		StartCoroutine(ClickMine());
	}

	IEnumerator ClickMine() {
		foreach (var mine in mines) {
			yield return null;
			if (!mine.flag) mine.Show_UI("mine");
		}
	}


	/// <summary>
	/// 右键点击了显示的数字
	/// </summary>
	/// <param name="id"></param>
	public void OnClickShow1(int id) {
		int x = id / column;
		int y = id % column;
		int cntf = 0;       // 统计周围标记的旗子数
		for (int i = 0; i < 8; i++) {
			int xt = x + jump[i, 0];
			int yt = y + jump[i, 1];
			if (IsGrid(xt, yt) && items[xt, yt].flag) cntf++;       // 统计周围旗子数
		}
		// Debug.Log(cntf + " " + ids[x, y]);
		if (cntf == ids[x, y]) {
			for (int i = 0; i < 8; i++) {
				int xt = x + jump[i, 0];
				int yt = y + jump[i, 1];
				// Debug.Log(items[xt, yt].flag);
				if (IsGrid(xt, yt) && !items[xt, yt].flag && !items[xt, yt].show) {           // 点击周围8个点
					if (ids[xt, yt] == -1) {
						OnClickMine0(xt * column + yt);       // 点击炸弹
					} else {
						OnClickNum0(xt * column + yt);        // 点击数字
					}
				}
			}
		}



	}

	/// <summary>
	/// 右键点击了隐藏的Item
	/// </summary>
	/// <param name="id"></param>
	public void OnClickHide1(int id) {
		int x = id / column;
		int y = id % column;
		if (items[x, y].flag) {     // 原来有旗子, 现在取消旗子
			items[x, y].Show_UI("hide");
			items[x, y].flag = false;
		} else {                    // 原来没有旗子, 现在添加旗子
			items[x, y].Show_UI("flag");
			items[x, y].flag = true;
		}
	}




	private void dfs(int x, int y, int s) {
		if (!IsGrid(x, y)) return;

		items[x, y].Show_Num(ids[x, y]);
		items[x, y].show = true;

		for (int i = 0; i < 8; i++) {
			int xt = x + jump[i, 0];
			int yt = y + jump[i, 1];
			// 下一节点: 在范围内, 没打开, 没标记
			if (IsGrid(xt, yt) && !items[xt, yt].show && !items[xt, yt].flag) {
				if (ids[xt, yt] == 0) {                 // 如果下一节点是0
					dfs(xt, yt, ids[xt, yt]);
				} else if (s == 0) {                    // 下一节点不是0, 当前节点是0
					items[xt, yt].Show_Num(ids[xt, yt]);
					items[xt, yt].show = true;
				}

			}
		}
	}

	public bool IsGrid(int x, int y) {
		return x >= 0 && x < row && y >= 0 && y < column;
	}
}
